#include <iostream>
using namespace std;
void _display_category(std::output_iterator_tag) {
    cout << "output iteraotr tag" << endl;
}
void _display_category(std::input_iterator_tag) {
    cout << "input iteraotr tag" << endl;
}
void _display_category(std::forward_iterator_tag) {
    cout << "forward iteraotr tag" << endl;
}
void _display_category(std::bidirectional_iterator_tag) {
    cout << "bidirectional iteraotr tag" << endl;
}
void _display_category(std::random_access_iterator_tag) {
    cout << "random access iteraotr tag" << endl;
}
#include <typeinfo>
template <class Iter> void display_category(const Iter& itr) {
    typedef typename iterator_traits<Iter>::iterator_category cgy;
    _display_category(cgy());

    cout<<"iter:typeid(itr):"<<typeid(itr).name()<<endl;
}
#include <array>
#include <deque>
#include <forward_list>
#include <list>
#include <vector>


#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <iterator>
void testIteratorCategory() {
    display_category(std::array<int, 10>::iterator());
    display_category(std::vector<int>::iterator());
    display_category(std::list<int>::iterator());
    display_category(std::forward_list<int>::iterator());
    display_category(std::deque<int>::iterator());

    display_category(std::set<int>::iterator());
    display_category(std::multiset<int>::iterator());
    display_category(std::unordered_set<int>::iterator());
    display_category(std::unordered_multiset<int>::iterator());

    display_category(std::map<int, int>::iterator());
    display_category(std::multimap<int, int>::iterator());
    display_category(std::unordered_map<int, int>::iterator());
    display_category(std::unordered_multimap<int, int>::iterator());
    display_category(std::istream_iterator<int>());
    display_category(std::ostream_iterator<int>(cout,""));
}